home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / rkeyboar.cpt / Reactive Keyboard ƒ / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-29  |  60.5 KB  |  2,226 lines

  1. #include <MacIncludes.h>
  2. #include "Rk.h"
  3. #include "Structs.h"
  4. #include "file+rk.h"
  5. #include "Offscreen.h"
  6. #include "Help.h"
  7. #include "utl.h"
  8.  
  9. /*   #define PERFORMANCE   */
  10. #define OPENCLOSES
  11.  
  12.  
  13.  
  14.  
  15. #ifdef PERFORMANCE
  16. #include <Perf.h>
  17. TP2PerfGlobals    ThePGlobals;
  18. #endif
  19.  
  20.  
  21. #define PRED_CLIP 0
  22. #define TEXT_CLIP 1
  23.  
  24.  
  25. extern pascal void AsmClikLoop();
  26. extern void _DataInit();
  27.  
  28. /* This routine is part of the MPW runtime library. This external
  29.    reference to it is done so that we can unload its segment, %A5Init. */
  30.  
  31.  
  32.  
  33. SysEnvRec    gMac;
  34. WindowPtr    gPredict,gText;
  35. Boolean        gHasWaitNextEvent;    /* set up by Initialize */
  36. Boolean        gHaveAUX;
  37. Boolean        gInBackground;        /* maintained by Initialize and DoEvent */
  38. short        gLogFileRef;
  39. short        gNumDocuments;        /* maintained by Initialize, DoNew, and DoCloseWindow */
  40. short        gContextBar=60;
  41. FontInfo     gFInfo,gNormFInfo;
  42. short        gSpecialFont;
  43. Rect        gHiliteRect;
  44. ControlHandle gPredScroll;
  45. Ptr            Hilite=HiliteMode;
  46. short        gPredScrollNum=0;
  47. GrafPort     goffScreen;
  48. Boolean        gDontSleep=false;
  49. PrefHandle    gPrefs,gOldPrefs,gStartPrefs;
  50. int            gSelLine=-1, gSelChar=-1;
  51. Boolean        gNewLine;
  52. int            gPrinting;
  53. short        gFileCount;
  54. Rect        gFreqRect,gOrderRect;
  55. Rect        gFreqPromptRect,gOrderPromptRect;
  56. MenuHandle    gFreqPop, gOrderPop;
  57. short        gLastFreq,gLastOrder;
  58.  
  59. extern        Boolean gNewFile;
  60. Str255        gFileName="\pUntitled";
  61. Boolean     gChanged;
  62. Boolean        gLowMem=false;
  63. Boolean        gReport=false;
  64.  
  65. extern        WindowPtr HelpWindow;        /* ptr to help window */
  66.  
  67.  
  68. extern        THPrint        gPrinterRecord;
  69.  
  70.     void AlertUser();
  71.     void EventLoop( void );
  72.     void DoEvent( EventRecord *event );
  73.     Boolean IsAppWindow( WindowPtr window );
  74.     Boolean IsDAWindow( WindowPtr window );
  75.     void AdjustMenus( void );
  76.     void DoMenuCommand( long menuResult );
  77.     void DoUpdate( WindowPtr window );
  78.     void DrawPredictWindow(WindowPtr window);
  79.     void DoActivate( WindowPtr window, Boolean becomingActive );
  80.     void DoContentClick( WindowPtr window, EventRecord *event );
  81.     void DoGrowWindow( WindowPtr window, EventRecord *event );
  82.     void DoZoomWindow( WindowPtr window, short part );
  83.     void ResizeWindow( WindowPtr window );
  84.     void Terminate( void );
  85.     Boolean DoCloseWindow( WindowPtr window );
  86.     void DrawNewPredictions(void);
  87.     void ReDrawPredictions(void);
  88.     void DrawPrediction(char *prediction,int right);
  89.     void SpecialLine(char *line,char *prediction);
  90.     pascal void VActionProc( ControlHandle control, short part );
  91.     pascal void HActionProc( ControlHandle control, short part );
  92.     pascal void PredActionProc( ControlHandle control, short part );
  93.     void DoKeyDown( EventRecord *event );
  94.     void DrawWindow( WindowPtr window );
  95.     void GetLocalUpdateRgn( WindowPtr window, RgnHandle localRgn );
  96.     void AdjustTE( WindowPtr window );
  97.     void AdjustHV( Boolean isVert, ControlHandle control, TEHandle docTE,
  98.                     Boolean canRedraw );
  99.     void AdjustScrollValues( WindowPtr window, Boolean canRedraw );
  100.     void AdjustScrollSizes( WindowPtr window );
  101.     void AdjustScrollbars( WindowPtr window, Boolean needsResize );
  102.     void CommonAction( ControlHandle control, short *amount );
  103.     void AdjustViewRect( TEHandle docTE );
  104.     void GetTERect( WindowPtr window, Rect *teRect );
  105.     pascal void PascalClikLoop();
  106.     pascal ProcPtr GetOldClikLoop();
  107.     void DoNew( void );
  108.     void DoIdle();
  109.     unsigned long GetSleep();
  110.     void NewContext();
  111.     void DoOpen();
  112.     void DoSave();
  113.     void DoPrefs();
  114.     void GetPrefs();
  115.     void DoAbout();
  116.     void SetCheckBox(dialog,item,state);
  117.     char *PathNameFromDirID(long DirID, short vRefNum, char *s);
  118.     char *PathNameFromWD(long vRefNum, char *s);    
  119.  
  120.     extern    void DoOpen();
  121.     extern    void DoSave();
  122.     extern    void AdjustCursor( Point mouse, RgnHandle region );
  123.     extern    void AdjustCurPred(Point mouse,RgnHandle region, WindowPtr window);
  124.     extern    void AdjustCurText(Point mouse,RgnHandle region, WindowPtr window);
  125.     extern     void GetGlobalRect (WindowPtr window, Rect *globalRect);
  126.  
  127.  
  128.  
  129.  
  130. extern int pred_number;
  131. int        num_buffers=1;
  132. char            output_string[1024], temp_str[1024];
  133. int             output_string_length;
  134. char            ed_context[MAX_CMD_LINE_LENGTH];
  135. /* extern  ED_STRUCT    editor_data; */
  136.  
  137. #define TopLeft(aRect)    (* (Point *) &(aRect).top)
  138. #define BotRight(aRect)    (* (Point *) &(aRect).bottom)
  139.  
  140.  
  141.  
  142. #pragma segment Main
  143.  
  144. main(){
  145.     
  146. #ifdef PERFORMANCE
  147.     if (!InitPerf(&ThePGlobals,
  148.             4,                    /* ms */
  149.             8,                    /* bytes */
  150.             true,                /* measure ROM code */
  151.             true,                 /* measure application code */
  152.             (StringPtr)"\pCODE",/* segments to measure */
  153.             0,                    /* Let the performance tools calculate the ROM id */
  154.             (StringPtr)"\p",    /* Let the performance tools find the ROM name */
  155.             false,                /* don't measure RAM */
  156.             0,                    /* low RAM address */
  157.             0xFFFFF,            /* high RAM address */
  158.             16                    /* RAM bucket size */
  159.         )){
  160.         DebugStr("\pInitPerf Failed!!!");
  161.         ExitToShell();
  162.     }
  163. #endif
  164. #ifdef PERFORMANCE
  165.     PerfControl(ThePGlobals,true);
  166. #endif
  167.     UnloadSeg((Ptr) _DataInit);        /* note that _DataInit must not be in Main! */
  168.     
  169.     MaxApplZone();                    /* expand the heap so code segments load at the top */
  170.  
  171.     Init();                            /* initialize the program */
  172.     UnloadSeg((Ptr) Init);    /* note that Initialize must not be in Main! */
  173.     EventLoop();
  174.  
  175. }
  176.  
  177.  
  178. #pragma segment Main
  179. void AlertUser(error)
  180.     short        error;
  181. {
  182.     short        itemHit;
  183.     Str255        message;
  184.  
  185.     SetCursor(&qd.arrow);
  186.     /* type Str255 is an array in MPW 3 */
  187.     GetIndString(message, rErrStrings, error);
  188.     ParamText(message, "", "", "");
  189.     
  190.     itemHit = Alert(rUserAlert, nil);
  191. } /* AlertUser */
  192.  
  193. #pragma segment Main
  194. void EventLoop()
  195. {
  196.     RgnHandle    cursorRgn;
  197.     Boolean        gotEvent;
  198.     EventRecord    event;
  199.  
  200.     cursorRgn = NewRgn();            /* we╒ll pass WNE an empty region the 1st time thru */
  201.     do {
  202.         /* use WNE if it is available */
  203. #ifdef PERFORMANCE
  204.     PerfControl(ThePGlobals,false);
  205. #endif
  206.         if ( gHasWaitNextEvent )
  207.             gotEvent = WaitNextEvent(everyEvent, &event, GetSleep(cursorRgn), cursorRgn);
  208.         else {
  209.             SystemTask();
  210.             gotEvent = GetNextEvent(everyEvent, &event);
  211.         }
  212. #ifdef PERFORMANCE
  213.     PerfControl(ThePGlobals,true);
  214. #endif
  215.         if ( gotEvent ) {
  216.             /* make sure we have the right cursor before handling the event */
  217.             AdjustCursor(event.where, cursorRgn);
  218.             DoEvent(&event);
  219.         }
  220.         else
  221.             DoIdle();                /* perform idle tasks when it╒s not our event */
  222.         /* change the cursor (and region) if necessary */
  223.         AdjustCursor(event.where, cursorRgn);
  224.     } while ( true );    /* loop forever; we quit via ExitToShell */
  225. } /*EventLoop*/
  226.  
  227. #pragma segment Main
  228. void DoIdle()
  229. {
  230.     WindowPtr    window;
  231.  
  232.     window = FrontWindow();
  233.     if ( window == gText )
  234.         TEIdle(((DocumentPeek) window)->docTE);
  235.  
  236.     if( gLowMem && !gReport){
  237.         gReport=true;
  238.         StopAlert(rLowMems,nil);
  239.     }
  240. } /*DoIdle*/
  241.  
  242. #pragma segment Main
  243. void DoEvent(event)
  244.     EventRecord    *event;
  245. {
  246.     short        part;
  247.     WindowPtr    window;
  248.     Boolean        hit;
  249.     char        key;
  250.     WindowObject    *whichObj;        /* ptr to object for window clicked in */
  251.     Boolean        Help=false;
  252.     Point        where;
  253.     unsigned long    newSize;
  254.  
  255.  
  256.     switch ( event->what ) {
  257.         case nullEvent:
  258.             /* we idle for null/mouse moved events ands for events which aren╒t
  259.                 ours (see EventLoop) */
  260.             DoIdle();
  261.             break;
  262.  
  263.         case mouseDown:
  264.             part = FindWindow(event->where, &window);
  265.             SetPort(window);
  266.             if (window && window == HelpWindow) {
  267.                 Help=true;
  268.                 whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  269.             }
  270.             switch ( part ) {
  271.                 case inMenuBar:                /* process a mouse menu command (if any) */
  272.                     AdjustMenus();
  273.                     DoMenuCommand(MenuSelect(event->where));
  274.                     break;
  275.                 case inSysWindow:            /* let the system handle the mouseDown */
  276.                     SystemClick(event, window);
  277.                     break;
  278.                 case inContent:
  279.                     if ( window != FrontWindow() ) {
  280.                         SelectWindow(window);
  281.                         /*DoContentClick(window,event);*/    /* use this line for "do first click" */
  282.                     } else if(Help){
  283.                         SetPort(window);
  284.                         where = event->where;
  285.                         GlobalToLocal(&where);
  286.                         if (whichObj->click) 
  287.                             (*whichObj->click)(where, event->modifiers);
  288.                     } else
  289.                         DoContentClick(window,event);
  290.                     break;
  291.                 case inDrag:                /* pass screenBits.bounds to get all gDevices */
  292.                     DragWindow(window, event->where, &qd.screenBits.bounds);
  293.                     break;
  294.                 case inGrow:
  295.                     if(window==gPredict){
  296.                         long    growsize;
  297.                         Rect    inval;
  298.                         int        oldhsize = window->portRect.right -window->portRect.left;
  299.  
  300.                         inval = qd.screenBits.bounds;
  301.                         inval.left = kMinPredWidth;
  302.                         inval.top = kMinPredHeight;
  303.                         growsize=GrowWindow(gPredict,event->where,&inval);
  304.                         if(growsize){
  305.                             SizeWindow(gPredict,LoWord(growsize),HiWord(growsize),1);
  306.                             SetRect(&inval,0,0,LoWord(growsize),HiWord(growsize));
  307.                             InvalRect(&inval);
  308.                             MoveControl(gPredScroll, window->portRect.right - kScrollbarAdjust, -1);
  309.                             SizeControl(gPredScroll, kScrollbarWidth, (window->portRect.bottom - 
  310.                                 window->portRect.top) - (kScrollbarAdjust - kScrollTweek));
  311.                             if(gContextBar>(LoWord(growsize)-kMinPredWidth/2))
  312.                                 gContextBar=LoWord(growsize)-(oldhsize-gContextBar);
  313.                             if(gContextBar<(kMinPredWidth/2)) gContextBar = kMinPredWidth/2;
  314.                         }
  315.                     }else if(window==gText)
  316.                         DoGrowWindow(window, event);
  317.                     else if(Help){
  318.                             SetPort(window);
  319.                         newSize = GrowWindow(window, event->where, 
  320.                             &whichObj->sizeRect);
  321.                         if (newSize && whichObj->grow) 
  322.                             (*whichObj->grow)(newSize >> 16, newSize & 0xffff);
  323.                     }
  324.                     break;
  325.                 case inGoAway:
  326.                     if(TrackGoAway(window,event->where)){
  327.                         if(Help){
  328.                             if (whichObj->close) (*whichObj->close)();
  329.                         }else{
  330.                             DoCloseWindow(window);            /* ignore the result */
  331.                         }
  332.                     }
  333.                     break;
  334.                 case inZoomIn:
  335.                 case inZoomOut:
  336.                     if (window==gPredict)
  337.                     {
  338.                         int        oldhsize = window->portRect.right -window->portRect.left;
  339.                         hit = TrackBox(window, event->where, part);
  340.                         if ( hit ) {
  341.                             SetPort(window);                /* the window must be the current port... */
  342.                             EraseRect(&window->portRect);    /* because of a bug in ZoomWindow */
  343.                             ZoomWindow(window, part, true);    /* note that we invalidate and erase... */
  344.                             InvalRect(&window->portRect);    /* to make things look better on-screen */
  345.                             MoveControl(gPredScroll, window->portRect.right - kScrollbarAdjust, -1);
  346.                             SizeControl(gPredScroll, kScrollbarWidth, (window->portRect.bottom - 
  347.                                 window->portRect.top) - (kScrollbarAdjust - kScrollTweek));
  348.                             if(gContextBar>((window->portRect.right-window->portRect.left)-kMinPredWidth/2))
  349.                                 gContextBar=(window->portRect.right-window->portRect.left)-(oldhsize-gContextBar);
  350.                             if(gContextBar<(kMinPredWidth/2)) gContextBar = kMinPredWidth/2;
  351.                         }
  352.                     } else if(window==gText)
  353.                         if ( TrackBox(window, event->where, part) )
  354.                             DoZoomWindow(window, part);
  355.                     break;
  356.             }
  357.             break;
  358.         case keyDown:
  359.         case autoKey:                        /* check for menukey equivalents */
  360.             if (event->what == keyDown || event->what == autoKey) {
  361.                 key = event->message & charCodeMask;
  362.                 switch (key) {
  363.                     case homeKey:
  364.                         key = upArrow;
  365.                         event->modifiers |= cmdKey | shiftKey;
  366.                         break;
  367.                     case endKey:
  368.                         key = downArrow;
  369.                         event->modifiers |= cmdKey | shiftKey;
  370.                         break;
  371.                     case helpKey:
  372.                         key = '?';
  373.                         event->modifiers |= cmdKey;
  374.                         break;
  375.                     case pageUpKey:
  376.                         key = upArrow;
  377.                         event->modifiers |= cmdKey;
  378.                         break;
  379.                     case pageDownKey:
  380.                         key = downArrow;
  381.                         event->modifiers |= cmdKey;
  382.                         break;
  383.                 }
  384.                 event->message = (event->message & ~charCodeMask) | key;
  385.             }
  386.  
  387.             key = event->message & charCodeMask;
  388.             if ( event->modifiers & cmdKey ){            /* Command key down */
  389.                 if ( event->what == keyDown ) {
  390.                     AdjustMenus();                        /* enable/disable/check menu items properly */
  391.                     DoMenuCommand(MenuKey(key));
  392.                 }
  393.             } else {
  394.                 if(FrontWindow()==HelpWindow){
  395.                     WindowObject *FrontObj = (WindowObject*)((WindowPeek)FrontWindow())->refCon;
  396.                     if (FrontObj->key) (*FrontObj->key)(key, event->modifiers);
  397.                 }else
  398.                     DoKeyDown(event);
  399.             }
  400.             break;
  401.         case activateEvt:
  402.             window = (WindowPtr)event->message;
  403.             if (window && window == HelpWindow) {
  404.                 whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  405.                 SetPort(window);
  406.                 if (event->modifiers & activeFlag) {
  407.                     if (whichObj->activate) (*whichObj->activate)();
  408.                 } else {
  409.                     if (whichObj->deactivate) (*whichObj->deactivate)();
  410.                 }
  411.             } else
  412.                 DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
  413.             break;
  414.         case updateEvt:
  415.             window = (WindowPtr)event->message;
  416.             if (window && window == HelpWindow) {
  417.                 whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  418.                 SetPort(window);
  419.                 BeginUpdate(window);
  420.                 EraseRect(&window->portRect);
  421.                 if (whichObj->update) (*whichObj->update)();
  422.                 EndUpdate(window);
  423.             } else
  424.                 DoUpdate((WindowPtr) event->message);
  425.             break;
  426.         case kOSEvent:
  427.             switch (event->message >> 24) {        /* high byte of message */
  428.                 case kMouseMovedMessage:
  429.                     DoIdle();                    /* mouse-moved is also an idle event */
  430.                     break;
  431.                 case kSuspendResumeMessage:        /* suspend/resume is also an activate/deactivate */
  432.                     gInBackground = (event->message & kResumeMask) == 0;
  433.                     window = FrontWindow();
  434.                     if (window && window == HelpWindow) {
  435.                         whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  436.                         SetPort(window);
  437.                         if (!gInBackground) {
  438.                             if (whichObj->activate) (*whichObj->activate)();
  439.                         } else {
  440.                             if (whichObj->deactivate) (*whichObj->deactivate)();
  441.                         }
  442.                     } else
  443.                         DoActivate(FrontWindow(), !gInBackground);
  444.                     break;
  445.             }
  446.             break;
  447.     }
  448. } /*DoEvent*/
  449.  
  450. #pragma segment Main
  451. unsigned long GetSleep(RgnHandle cursorRgn)
  452. {
  453.     long        sleep;
  454.     WindowPtr    window;
  455.     TEHandle    te;
  456.     Point        theMouse;
  457.  
  458.     sleep = 50;                        /* default value for sleep */
  459.     GetMouse(&theMouse);
  460.     LocalToGlobal(&theMouse);
  461.     if(!PtInRgn(theMouse,cursorRgn)){
  462.         return(0);
  463.     }
  464.     if ( !gInBackground ) {
  465.         window = FrontWindow();            /* and the front window is ours... */
  466.         if ( IsAppWindow(window) && (window != gPredict) && (window!=HelpWindow) ) {
  467.             te = ((DocumentPeek) (window))->docTE;    /* and the selection is an insertion point... */
  468.             if ( (*te)->selStart == (*te)->selEnd )
  469.                 sleep = GetCaretTime();        /* blink time for the insertion point */
  470.         }
  471.     }
  472.     return sleep;
  473. } /*GetSleep*/
  474.  
  475. #pragma segment Main
  476. pascal void nullEraseRect(GrafVerb verb,const Rect *r)
  477. {
  478.     if(verb!=erase)
  479.     {
  480.         StdRect(verb,r);
  481.     }
  482. }
  483.  
  484.  
  485.  
  486. void SetCheckBox(dialog,item,state)
  487.     DialogPtr    dialog;
  488.     short        item;
  489.     short        state;
  490. {
  491.     short        kind;
  492.     Handle        h;
  493.     Rect        r;
  494.  
  495.     GetDItem(dialog,item,&kind,&h,&r);
  496.     SetCtlValue((ControlHandle)h,state);
  497. }
  498.  
  499. #pragma segment Main
  500. Boolean IsAppWindow(window)
  501.     WindowPtr    window;
  502. {
  503.     short        windowKind;
  504.  
  505.     if ( window == nil )
  506.         return false;
  507.     else {    /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
  508.         windowKind = ((WindowPeek) window)->windowKind;
  509.         return (windowKind >= userKind) || (windowKind == dialogKind);
  510.     }
  511. } /*IsAppWindow*/
  512.  
  513.  
  514. /* Check to see if a window belongs to a desk accessory. */
  515.  
  516. #pragma segment Main
  517. Boolean IsDAWindow(window)
  518.     WindowPtr    window;
  519. {
  520.     if ( window == nil )
  521.         return false;
  522.     else    /* DA windows have negative windowKinds */
  523.         return ((WindowPeek) window)->windowKind < 0;
  524. } /*IsDAWindow*/
  525.  
  526. #pragma segment Main
  527. void AdjustMenus()
  528. {
  529.     WindowPtr    window;
  530.     MenuHandle    menu;
  531.     long        offset;
  532.     Boolean        undo;
  533.     Boolean        cutCopyClear;
  534.     Boolean        paste;
  535.     TEHandle    te;
  536.     WindowObject    *whichObj;        /* ptr to object for window clicked in */
  537.  
  538.     window = FrontWindow();
  539.     if(window&&window==HelpWindow){
  540.         whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  541.         if (whichObj->adjust) (*whichObj->adjust)();
  542.     } else {
  543.  
  544.         menu = GetMHandle(mFile);
  545.         
  546.         EnableItem(menu, iPrime);    /* We can Always Prime */
  547.         EnableItem(menu, iPageSetup); /* Ditto */
  548.     
  549.     
  550.     #ifndef OPENCLOSES 
  551.         if ( gNumDocuments < kMaxOpenDocuments ){
  552.             EnableItem(menu, iNew);        /* New is enabled when we can open more documents */
  553.             EnableItem(menu, iOpen);    /* Open as well */
  554.         } else { 
  555.             DisableItem(menu, iNew);
  556.             DisableItem(menu, iOpen);
  557.         }
  558.     #else
  559.             EnableItem(menu, iNew);        /* New is enabled when we can open more documents */
  560.             EnableItem(menu, iOpen);    /* Open as well */
  561.     #endif
  562.         if (IsAppWindow(window))            /* Close is enabled when there is a window to close */
  563.             EnableItem(menu, iClose);
  564.         else
  565.             DisableItem(menu, iClose);
  566.         if (IsAppWindow(window)){            /* Save is enabled when there is a window to save */
  567.             EnableItem(menu, iSave);
  568.             EnableItem(menu, iSaveAs);
  569.             if(!gNewFile){
  570.                 EnableItem(menu, iRevert);
  571.             } else {
  572.                 DisableItem(menu, iRevert);
  573.             }
  574.         } else {
  575.             DisableItem(menu, iSave);
  576.             DisableItem(menu, iSaveAs);
  577.             DisableItem(menu, iRevert);
  578.         }
  579.         if (window==gText){            /* Print is enabled when there is a window to Print */
  580.             EnableItem(menu, iPrint);
  581.         } else {
  582.             DisableItem(menu, iPrint);
  583.         }
  584.     
  585.         
  586.         menu = GetMHandle(mEdit);
  587.         undo = false;
  588.         cutCopyClear = false;
  589.         paste = false;
  590.         if ( IsDAWindow(window) ) {
  591.             undo = true;                /* all editing is enabled for DA windows */
  592.             cutCopyClear = true;
  593.             paste = true;
  594.         } else if ( IsAppWindow(window) ) {
  595.             te = ((DocumentPeek) window)->docTE;
  596.             if ( (*te)->selStart < (*te)->selEnd )
  597.                 cutCopyClear = true;
  598.                 /* Cut, Copy, and Clear is enabled for app. windows with selections */
  599.             if ( GetScrap(nil, 'TEXT', &offset) )
  600.                 paste = true;            /* if there╒s any text in the clipboard, paste is enabled */
  601.         }
  602.         if ( undo )
  603.             EnableItem(menu, iUndo);
  604.         else
  605.             DisableItem(menu, iUndo);
  606.         if ( cutCopyClear ) {
  607.             EnableItem(menu, iCut);
  608.             EnableItem(menu, iCopy);
  609.             EnableItem(menu, iClear);
  610.         } else {
  611.             DisableItem(menu, iCut);
  612.             DisableItem(menu, iCopy);
  613.             DisableItem(menu, iClear);
  614.         }
  615.         if ( paste )
  616.             EnableItem(menu, iPaste);
  617.         else
  618.             DisableItem(menu, iPaste);
  619.     }
  620. } /*AdjustMenus*/
  621.  
  622.  
  623. #pragma segment Main
  624. void DoMenuCommand(menuResult)
  625.     long        menuResult;
  626. {
  627.     short        menuID, menuItem;
  628.     short        daRefNum;
  629.     Str255        daName;
  630.     OSErr        saveErr;
  631.     TEHandle    te;
  632.     WindowPtr    window;
  633.     Handle        aHandle;
  634.     long        oldSize, newSize;
  635.     long        total, contig;
  636.     WindowObject    *whichObj;        /* ptr to object for window clicked in */
  637.     Boolean        Help=false;
  638.  
  639.     window = FrontWindow();
  640.     if(window==HelpWindow){
  641.         whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  642.         Help=true;
  643.     }
  644.     menuID = HiWord(menuResult);    /* use macros for efficiency to... */
  645.     menuItem = LoWord(menuResult);    /* get menu item number and menu number */
  646.     switch ( menuID ) {
  647.         case mApple:
  648.             switch ( menuItem ) {
  649.                 case iAbout:        /* bring up Dialog for About */
  650.                     help_Open(0);
  651.                     break;
  652.                 default:            /* all non-About items in this menu are DAs et al */
  653.                     /* type Str255 is an array in MPW 3 */
  654.                     GetItem(GetMHandle(mApple), menuItem, daName);
  655.                     daRefNum = OpenDeskAcc(daName);
  656.                     break;
  657.             }
  658.             break;
  659.         case mFile:
  660.             switch ( menuItem ) {
  661.                 case iNew:
  662. #ifdef OPENCLOSES
  663.                     if(gNumDocuments == 1){
  664.                         if(DoCloseWindow(gText))
  665.                             DoNew();
  666.                     }else                        
  667. #endif                        
  668.                     DoNew();
  669.                     break;
  670.                 case iOpen:
  671. #ifdef OPENCLOSES
  672.                     if(gNumDocuments == 1){
  673.                         if(DoCloseWindow(gText))
  674.                             DoOpen();
  675.                     }else                        
  676. #endif                        
  677.                     DoOpen();
  678.                     break;
  679.                 case iPrime:
  680.                     DoPrime();
  681.                     break;
  682.                 case iSave:
  683.                     if(Help){
  684.                         if (whichObj->save) (*whichObj->save)();
  685.                     } else
  686.                         DoSave();
  687.                     break;
  688.                 case iSaveAs:
  689.                     if(Help){
  690.                         if (whichObj->save) (*whichObj->save)();
  691.                     } else
  692.                         DoSaveAs(gFileName);
  693.                     break;
  694.                 case iRevert:
  695.                     DoRevert();
  696.                     break;
  697.                 case iPageSetup:
  698.                     if(Help){
  699.                         if (whichObj->pageSetup){
  700.                             PrOpen();
  701.                             (*whichObj->pageSetup)();
  702.                             PrClose();
  703.                         }
  704.                     } else{
  705.                         PrOpen();
  706.                         if(PrError() == noErr)
  707.                             PrStlDialog(gPrinterRecord);
  708.                         PrClose();
  709.                     }
  710.                     break;
  711.                 case iPrint:
  712.                     if(Help){
  713.                         if (whichObj->print)
  714.                             PrOpen();
  715.                             (*whichObj->print)(false);
  716.                             PrClose();
  717.                     } else {
  718.                         SetPort(gText);
  719.                         PrintText(((DocumentPeek) FrontWindow())->docTE);
  720.                     }
  721.                     break;
  722.                 case iClose:
  723.                     if(Help){
  724.                         if (whichObj->close) (*whichObj->close)();
  725.                     } else
  726.                         DoCloseWindow(FrontWindow());            /* ignore the result */
  727.                     break;
  728.                 case iQuit:
  729.                     Terminate();
  730.                     break;
  731.             }
  732.             break;
  733.         case mEdit:                    /* call SystemEdit for DA editing & MultiFinder */
  734.             if ( !SystemEdit(menuItem-1) ) {
  735.                 gChanged = true;
  736.                 te = ((DocumentPeek) FrontWindow())->docTE;
  737.                 switch ( menuItem ) {
  738.                     case iCut:
  739.                         if ( ZeroScrap() == noErr ) {
  740.                             PurgeSpace(&total, &contig);
  741.                             if ((*te)->selEnd - (*te)->selStart + kTESlop > contig)
  742.                                 AlertUser(eNoSpaceCut);
  743.                             else {
  744.                                 TECut(te);
  745.                                 if ( TEToScrap() != noErr ) {
  746.                                     AlertUser(eNoCut);
  747.                                     ZeroScrap();
  748.                                 }
  749.                             }
  750.                         }
  751.                         break;
  752.                     case iCopy:
  753.                         if ( ZeroScrap() == noErr ) {
  754.                             TECopy(te);    /* after copying, export the TE scrap */
  755.                             if ( TEToScrap() != noErr ) {
  756.                                 AlertUser(eNoCopy);
  757.                                 ZeroScrap();
  758.                             }
  759.                         }
  760.                         break;
  761.                     case iPaste:    /* import the TE scrap before pasting */
  762.                         if ( TEFromScrap() == noErr ) {
  763.                             if ( TEGetScrapLen() + ((*te)->teLength -
  764.                                 ((*te)->selEnd - (*te)->selStart)) > kMaxTELength )
  765.                                 AlertUser(eExceedPaste);
  766.                             else {
  767.                                 aHandle = (Handle) TEGetText(te);
  768.                                 oldSize = GetHandleSize(aHandle);
  769.                                 newSize = oldSize + TEGetScrapLen() + kTESlop;
  770.                                 SetHandleSize(aHandle, newSize);
  771.                                 saveErr = MemError();
  772.                                 SetHandleSize(aHandle, oldSize);
  773.                                 if (saveErr != noErr)
  774.                                     AlertUser(eNoSpacePaste);
  775.                                 else
  776.                                     TEPaste(te);
  777.                             }
  778.                         }
  779.                         else
  780.                             AlertUser(eNoPaste);
  781.                         break;
  782.                     case iClear:
  783.                         TEDelete(te);
  784.                         break;
  785.                 }
  786.             AdjustScrollbars(window, false);
  787.             AdjustTE(window);
  788.             }
  789.             break;
  790.         case mOptions:
  791.             switch ( menuItem ) {
  792.                 case iModelOpts:        /* bring up Dialog for Prefs */
  793.                     DoPrefs();
  794.                     break;
  795.             }
  796.             break;
  797.  
  798.     }
  799.     HiliteMenu(0);                    /* unhighlight what MenuSelect (or MenuKey) hilited */
  800. } /*DoMenuCommand*/
  801.  
  802. #pragma segment Main
  803. void DoUpdate( WindowPtr window )
  804. {
  805.     if(window==gPredict){
  806.         DrawPredictWindow(gPredict);
  807.     } else if ( IsAppWindow(window) ) {
  808.         BeginUpdate(window);                /* this sets up the visRgn */
  809.         if ( ! EmptyRgn(window->visRgn) )    /* draw if updating needs to be done */
  810.             DrawWindow(window);
  811.         EndUpdate(window);
  812.     }
  813. } /*DoUpdate*/
  814.     
  815.  
  816. void DrawPredictWindow(WindowPtr window)
  817. {
  818.     Rect        globalRect;
  819.     Boolean     drawNeeded;
  820.     BitMapPtr    backMap,selectMap;
  821.     BitMap        MyMap=window->portBits;
  822.     Rect        Clip;
  823.     
  824.     SetPort(window);
  825.  
  826.     PushClip(PRED_CLIP);    
  827.     
  828.     SetRect(&Clip,window->portRect.left,window->portRect.top,window->portRect.right, window->portRect.bottom);
  829.     ClipRect(&Clip);
  830.  
  831.     GetGlobalRect(window,&globalRect);
  832.     
  833.     if(CheckBoundsOffscreen(((OffscreenPeek)window)->fSelectHandle,&globalRect, &drawNeeded)) /* Handle Memerr? */;
  834.  
  835.     BeginUpdateOffscreen(((OffscreenPeek)window)->fSelectHandle,window);
  836.     
  837.     if(CheckBoundsOffscreen(((OffscreenPeek)window)->fBackHandle,&globalRect, &drawNeeded)) /* Handle Memerr? */;
  838.     
  839.     if(drawNeeded){
  840.         BeginOffscreenDrawing(((OffscreenPeek)window)->fBackHandle,window);
  841.          EraseRect(&window->portRect);
  842.         ReDrawPredictions(); 
  843.         DrawGrowIcon(window);
  844.         DrawControls(window);
  845.         EndOffscreenDrawing(((OffscreenPeek)window)->fBackHandle);
  846.     }
  847.     backMap   = GetMap(((OffscreenPeek)window)->fBackHandle);
  848.     selectMap = GetMap(((OffscreenPeek)window)->fSelectHandle);
  849.     
  850.     if(backMap){
  851.         ForeColor(blackColor);
  852.         BackColor(whiteColor);
  853.         if(selectMap){
  854.             CopyBits(backMap, selectMap, &window->portRect, &window->portRect, srcCopy, nil);
  855.         }else{
  856.             CopyBits(backMap, &MyMap, &window->portRect, &window->portRect, srcCopy, nil);
  857.         }
  858.         ValidRectOffscreen(((OffscreenPeek)window)->fBackHandle, nil, &window->portRect);
  859.     }
  860.  
  861.  
  862.     EndUpdateOffscreen(((OffscreenPeek)window)->fSelectHandle,window);
  863.      ClipRect(&(window->portRect));
  864.     DrawGrowIcon(window);
  865.     DrawControls(window);
  866.     SetPort(gPredict);
  867.     PopClip(PRED_CLIP);
  868. }
  869.  
  870. #pragma segment Main
  871. void DoActivate(window, becomingActive)
  872.     WindowPtr    window;
  873.     Boolean        becomingActive;
  874. {
  875.     RgnHandle    tempRgn, clipRgn;
  876.     Rect        growRect;
  877.     DocumentPeek doc;
  878.     Rect        TextRect;
  879.     TEHandle    te;
  880.  
  881.     if(IsAppWindow(window)){
  882.         if (window != gPredict) {
  883.             SetPort(window);
  884.             doc = (DocumentPeek) window;
  885.             if ( becomingActive ) {
  886.                 /*    since we don╒t want TEActivate to draw a selection in an area where
  887.                     we╒re going to erase and redraw, we╒ll clip out the update region
  888.                     before calling it. */
  889.                 tempRgn = NewRgn();
  890.                 clipRgn = NewRgn();
  891.                 GetLocalUpdateRgn(window, tempRgn);            /* get localized update region */
  892.                 GetClip(clipRgn);
  893.                 DiffRgn(clipRgn, tempRgn, tempRgn);            /* subtract updateRgn from clipRgn */
  894.                 SetClip(tempRgn);
  895.                 TEActivate(doc->docTE);
  896.                 SetClip(clipRgn);                            /* restore the full-blown clipRgn */
  897.                 DisposeRgn(tempRgn);
  898.                 DisposeRgn(clipRgn);
  899.                 
  900.                 /* the controls must be redrawn on activation: */
  901.                 (*doc->docVScroll)->contrlVis = kControlVisible;
  902.                 (*doc->docHScroll)->contrlVis = kControlVisible;
  903.                 InvalRect(&(*doc->docVScroll)->contrlRect);
  904.                 InvalRect(&(*doc->docHScroll)->contrlRect);
  905.                 /* the growbox needs to be redrawn on activation: */
  906.                 growRect = window->portRect;
  907.                 /* adjust for the scrollbars */
  908.                 growRect.top = growRect.bottom - kScrollbarAdjust;
  909.                 growRect.left = growRect.right - kScrollbarAdjust;
  910.                 InvalRect(&growRect);
  911.                         
  912.             }
  913.             else {        
  914.                 TEDeactivate(doc->docTE);
  915.                 /* the controls must be hidden on deactivation: */
  916.                 HideControl(doc->docVScroll);
  917.                 HideControl(doc->docHScroll);
  918.                 /* the growbox should be changed immediately on deactivation: */
  919.                 DrawGrowIcon(window);
  920.             }
  921.         } else {
  922.             te = ((DocumentPeek) gText)->docTE;
  923.             SetPort(gPredict);
  924.             if( becomingActive ) {
  925.                 Rect inval=(*gPredScroll)->contrlRect;
  926.                 inval.bottom+=16;
  927.                 (*gPredScroll)->contrlVis = kControlVisible;
  928.                 InvalRect(&inval);
  929.             }else{
  930.                 Rect inval=(*gPredScroll)->contrlRect;
  931.     
  932.                 
  933.                 HideControl(gPredScroll);
  934.                 inval.bottom+=16;
  935.                 InvalRectOffscreen(((OffscreenPeek)gPredict)->fBackHandle,gPredict,&inval);
  936.                 InvalRectOffscreen(((OffscreenPeek)gPredict)->fSelectHandle,gPredict,&inval);
  937.                 SetPort(gText);
  938.                 SetRect(&TextRect,(*te)->selRect.left
  939.                                     ,(*te)->selRect.top,
  940.                                     (*te)->selRect.left+(goffScreen.portBits.bounds.right -
  941.                                     goffScreen.portBits.bounds.left),
  942.                                     (*te)->selRect.top+
  943.                                     gNormFInfo.ascent+gNormFInfo.descent
  944.                                     +gNormFInfo.leading);
  945.                 InvalRect(&TextRect);
  946.                 SetPort(gPredict);
  947.             }
  948.         }
  949.     }
  950. } /*DoActivate*/
  951.  
  952. #pragma segment Main
  953. void DoContentClick( WindowPtr window, EventRecord *event )
  954. {
  955.     Point        mouse;
  956.     ControlHandle control;
  957.     short        part, value;
  958.     Boolean        shiftDown;
  959.     DocumentPeek doc;
  960.     Rect        teRect;
  961.     Rect        MoveRect,LimitRect,SlopRect,iBeamRect;
  962.     RgnHandle    MoveRgn;
  963.     long        offset;
  964.     long        Count;
  965.     char        prediction[100];
  966.     char        line[100];
  967.     
  968.     SetPort(window);
  969.     mouse = event->where;                            /* get the click position */
  970.     GlobalToLocal(&mouse);
  971.  
  972.     if (window==gPredict) {
  973.         MoveRgn=NewRgn();
  974.         SetRect(&MoveRect,gContextBar-1,0,gContextBar+2,
  975.             gPredict->portRect.bottom-gPredict->portRect.top-16);
  976.         SetRect(&iBeamRect,0,2,
  977.             (gPredict->portRect.right-gPredict->portRect.left)-18,
  978.             (gPredict->portRect.bottom-gPredict->portRect.top)-18 );
  979.  
  980.         if(PtInRect(mouse,&MoveRect)){
  981.             RectRgn(MoveRgn, &MoveRect);
  982.             SlopRect=gPredict->portRect;
  983.             LimitRect=gPredict->portRect;
  984.             InsetRect(&LimitRect,30,0);
  985.             offset=DragGrayRgn(MoveRgn,mouse,&LimitRect,&SlopRect,hAxisOnly,nil);
  986.             if((short)LoWord(offset)!=(short)0x8000){
  987.                 gContextBar+=LoWord(offset);
  988.                 DrawNewPredictions();
  989.             }
  990.         }else if(PtInRect(mouse,&iBeamRect)){
  991.             if(mouse.h>gContextBar){
  992.                 pred_number=(mouse.v-2)/
  993.                 (gFInfo.ascent+gFInfo.descent+gFInfo.leading)+gPredScrollNum;
  994.                 if((pred_number<((gPredict->portRect.bottom-gPredict->portRect.top-20)/
  995.                     (gFInfo.ascent+gFInfo.descent+gFInfo.leading))+gPredScrollNum)&&pred_number<96){
  996.                     make_a_prediction(prediction);
  997.                     SpecialLine(line,prediction);
  998.                     Count=1;
  999.                     while(((TextWidth(line,0,Count++)+gContextBar+5)<mouse.h) 
  1000.                         && *(line+Count-1));
  1001.                     
  1002.                     TEInsert(prediction,Count-1,((DocumentPeek)gText)->docTE);
  1003.                     gChanged = true;
  1004.                     TEDelete(((DocumentPeek)gText)->docTE);
  1005.                     NewContext();
  1006.                     update_the_model();
  1007.                     DrawNewPredictions();
  1008.                 }
  1009.             }else{
  1010.                 char buffer[100];
  1011.                 CharsHandle TEText=TEGetText(((DocumentPeek)gText)->docTE);
  1012.                 Count=(*((DocumentPeek)gText)->docTE)->selStart>100?(*((DocumentPeek)gText)->docTE)->selStart-100:0;
  1013.                 strncpy(buffer,((char *)*TEText)+Count,(*((DocumentPeek)gText)->docTE)->selStart-Count);
  1014.                 
  1015.                 SpecialLine(buffer,buffer);
  1016.                 Count=(*((DocumentPeek)gText)->docTE)->selStart - (((gContextBar-2)-mouse.h)/CharWidth(' '));
  1017.                 if(Count< 0 ) Count=0;
  1018.                 /*
  1019.                 Count=(*((DocumentPeek)gText)->docTE)->selStart;
  1020.  
  1021.                 while(((gContextBar-2)-(TextWidth(buffer,Count,(*((DocumentPeek)gText)->docTE)->selStart-Count))>mouse.h) 
  1022.                         && Count)Count--;
  1023.                 */            
  1024.                 TESetSelect(Count,(*((DocumentPeek)gText)->docTE)->selEnd,((DocumentPeek)gText)->docTE);
  1025.                 TEDelete(((DocumentPeek)gText)->docTE);
  1026.                 gChanged = true;
  1027.                 DrawWindow(gText);
  1028.                 NewContext();
  1029.                 DrawNewPredictions();
  1030.             }
  1031.         }else{
  1032.             part = FindControl(mouse, window, &control);
  1033.             SetPort(gPredict);
  1034.             switch ( part ) {
  1035.                 case 0:                            /* do nothing for viewRect case */
  1036.                     break;
  1037.                 case inThumb:
  1038.                     if ( control == gPredScroll ){
  1039.                         PushClip(PRED_CLIP);
  1040.                         ClipRect(&(gPredict->portRect));
  1041.                         value = GetCtlValue(control);
  1042.                         part = TrackControl(control, mouse, nil);
  1043.                         gPredScrollNum=GetCtlValue(control);
  1044.                         PopClip(PRED_CLIP);
  1045.                     }else
  1046.                         DebugStr("FindControl returned inThumb to strange Control");
  1047.                     break;
  1048.                 default:                        /* they clicked in an arrow, so track & scroll */
  1049.                     if ( control == gPredScroll )
  1050.                         value = TrackControl(control, mouse, (ProcPtr) PredActionProc);
  1051.                     break;
  1052.             }
  1053.             DrawNewPredictions();
  1054.         }
  1055.         DisposeRgn(MoveRgn);
  1056.     } else if ( IsAppWindow(window) ) {
  1057.         doc = (DocumentPeek) window;
  1058.         /* see if we are in the viewRect. if so, we won╒t check the controls */
  1059.         GetTERect(window, &teRect);
  1060.         if ( PtInRect(mouse, &teRect) ) {
  1061.             /* see if we need to extend the selection */
  1062.             shiftDown = (event->modifiers & shiftKey) != 0;    /* extend if Shift is down */
  1063.             TEClick(mouse, shiftDown, doc->docTE);
  1064.             NewContext();
  1065.             DrawNewPredictions();
  1066.         } else {
  1067.             part = FindControl(mouse, window, &control);
  1068.             switch ( part ) {
  1069.                 case 0:                            /* do nothing for viewRect case */
  1070.                     break;
  1071.                 case inThumb:
  1072.                     value = GetCtlValue(control);
  1073.                     part = TrackControl(control, mouse, nil);
  1074.                     if ( part != 0 ) {
  1075.                         value -= GetCtlValue(control);
  1076.                         /* value now has CHANGE in value; if value changed, scroll */
  1077.                         if ( value != 0 )
  1078.                             if ( control == doc->docVScroll )
  1079.                                 TEScroll(0, value * (*doc->docTE)->lineHeight, doc->docTE);
  1080.                             else
  1081.                                 TEScroll(value, 0, doc->docTE);
  1082.                     }
  1083.                     break;
  1084.                 default:                        /* they clicked in an arrow, so track & scroll */
  1085.                     if ( control == doc->docVScroll )
  1086.                         value = TrackControl(control, mouse, (ProcPtr) VActionProc);
  1087.                     else
  1088.                         value = TrackControl(control, mouse, (ProcPtr) HActionProc);
  1089.                     break;
  1090.             }
  1091.             DrawNewPredictions();
  1092.         }
  1093.     }
  1094. } /*DoContentClick*/
  1095.  
  1096.  
  1097. #pragma segment Main
  1098. void Terminate()
  1099. {
  1100.     WindowPtr    aWindow;
  1101.     Boolean        closed;
  1102. #ifdef PERFORMANCE
  1103.     int    perferr;
  1104. #endif
  1105.  
  1106.     
  1107.     closed = true;
  1108.     do {
  1109.         aWindow = FrontWindow();                /* get the current front window */
  1110.         if (aWindow != nil);
  1111.             closed = DoCloseWindow(aWindow);    /* close this window */    
  1112.     }
  1113.     while (closed && (aWindow != nil));
  1114.     if (closed){
  1115. #ifdef PERFORMANCE
  1116.         perferr=PerfDump(ThePGlobals,"\pPerform.out", true, 80);
  1117.         if(perferr!=noErr)
  1118.         {
  1119.             DebugStr("\pPerfDump Failed!!");
  1120.             ExitToShell();
  1121.         }
  1122.         TermPerf(ThePGlobals);
  1123. #endif
  1124.  
  1125.         ExitToShell(); /* exit if no cancellation */
  1126.     }
  1127. } /*Terminate*/
  1128.  
  1129. #pragma segment Main
  1130. Boolean DoCloseWindow(window)
  1131.     WindowPtr    window;
  1132. {
  1133.  
  1134.     WindowObject    *whichObj;
  1135.         short        itemHit;
  1136.     
  1137.  
  1138.     if ( IsDAWindow(window) )
  1139.         CloseDeskAcc(((WindowPeek) window)->windowKind);
  1140.     else if ( IsAppWindow(window) ){
  1141.         if(window==HelpWindow){
  1142.             whichObj = (WindowObject*)((WindowPeek)window)->refCon;
  1143.             if (whichObj->close) (*whichObj->close)();
  1144.         }else{
  1145.             SetCursor(&qd.arrow);
  1146.             ParamText(gFileName, "\pClosing", "", "");
  1147.             
  1148.             if(gChanged) itemHit = Alert(rCloseAlert, nil);
  1149.             else         itemHit = iNo;
  1150.             switch(itemHit){
  1151.             
  1152.             case iYes:
  1153.                 DoSave();
  1154.                 if(gNewFile) return false;
  1155.             case iNo:
  1156.                 gNumDocuments--;
  1157.                 CloseWindow(gPredict);
  1158.                 CloseWindow(gText);
  1159.                 return true;
  1160.                 break;
  1161.             case iCancel:
  1162.                 return false;
  1163.                 break;
  1164.             }
  1165.         }
  1166.     }
  1167.     return true;
  1168. } /*DoCloseWindow*/
  1169.  
  1170. #pragma segment Main
  1171. void FileSystemError(Str255 FileName,Str255 doing, OSErr err, Boolean fatal)
  1172. {
  1173.     DialogPtr    ErrorDLOG;
  1174.     Str255        ErrorString;
  1175.     short        hit;
  1176.     
  1177.     NumToString((long)err,&ErrorString);
  1178.     ParamText(fatal?"\pfatal ":"\p",doing,FileName,ErrorString);
  1179.     ErrorDLOG=GetNewDialog(rFileErrorDialog,nil, (void *) -1);
  1180.     do{
  1181.         ModalDialog(nil,&hit);
  1182.     }while(hit!=1);
  1183.     DisposDialog(ErrorDLOG);
  1184.     if(fatal) ExitToShell();
  1185. }
  1186.  
  1187. void DrawNewPredictions()
  1188. {
  1189.     InvalRectOffscreen(((OffscreenPeek)gPredict)->fBackHandle,gPredict,&gPredict->portRect);
  1190.     InvalRectOffscreen(((OffscreenPeek)gPredict)->fSelectHandle,gPredict,&gPredict->portRect);
  1191.     DrawPredictWindow(gPredict); 
  1192. }
  1193.  
  1194. #pragma segment Main
  1195. void ReDrawPredictions()
  1196. {
  1197.     char         prediction[100];
  1198.     char        buffer[100];
  1199.     Point         penpt;
  1200.     CharsHandle    TEText;
  1201.     TEHandle    te;
  1202.     int            Count;
  1203.     
  1204.  
  1205.     te = ((DocumentPeek) gText)->docTE;
  1206.     PenSize(2,2);
  1207.     ForeColor(blackColor);
  1208.     MoveTo(gContextBar,0);
  1209.     LineTo(gContextBar,gPredict->portRect.bottom-gPredict->portRect.top-16);
  1210.     PenSize(1,1);
  1211.     MoveTo(gContextBar+5,4+(gFInfo.ascent));
  1212.     for(pred_number=gPredScrollNum;
  1213.         pred_number<((gPredict->portRect.bottom-gPredict->portRect.top-20)/
  1214.         (gFInfo.ascent+gFInfo.descent+gFInfo.leading))+gPredScrollNum;
  1215.         pred_number++){
  1216.         if(pred_number<96){
  1217.             make_a_prediction(prediction);
  1218.             DrawPrediction(prediction,(gPredict->portRect.right-gPredict->portRect.left));
  1219.         }
  1220.         GetPen(&penpt);
  1221.         Move(-(penpt.h-gContextBar-5),gFInfo.ascent+gFInfo.descent+gFInfo.leading);
  1222.     }
  1223.     TEText=TEGetText(te);
  1224.     for(Count=(*te)->selStart;(Count>0)&&
  1225.         ((TextWidth((Ptr)(*TEText),Count,(*te)->selStart-Count))<(gContextBar-2))
  1226.         ;Count--);
  1227.     strncpy(buffer,((char *)*TEText)+Count,(*te)->selStart-Count);
  1228.     SpecialLine(buffer,buffer);
  1229.     if((*te)->selStart==0){
  1230.         MoveTo((gContextBar-2)-TextWidth("(NONE)",0,6),4+(gFInfo.ascent));
  1231.         DrawString("\p(NONE)");
  1232.     }
  1233.     else
  1234.     {
  1235.         MoveTo((gContextBar-2)-TextWidth(buffer,0,
  1236.         (*te)->selStart-Count), 4+(gFInfo.ascent));
  1237.         DrawText(buffer,0,(*te)->selStart-Count);
  1238.     }
  1239. }
  1240.  
  1241. #pragma segment Main
  1242. void DrawPrediction(char *prediction,int right)
  1243. {
  1244.     Point penpt;
  1245.     int x;
  1246.     char line[128];
  1247.  
  1248.     GetPen(&penpt);
  1249.     SpecialLine(line,prediction);
  1250.     for(x=0;(TextWidth(line,0,x)<((right-penpt.h)-(kScrollbarWidth+3)))&&line[x];x++);
  1251.     if(x>0)    DrawText(line,0,x);
  1252. }
  1253.  
  1254. #pragma segment Main
  1255. void SpecialLine(char *line,char *prediction)
  1256. {
  1257.     if((*gPrefs)->pshowSpecial){
  1258.         while(*prediction){
  1259.             switch (*prediction){
  1260.             case 13:    *line++ = kCrSpec;
  1261.                         prediction++;
  1262.                         break;
  1263.             case 32:    *line++ = kSpSpec;
  1264.                         prediction++;
  1265.                         break;
  1266.             case 9:        *line++ = kTabSpec;
  1267.                         prediction++;
  1268.                         break;
  1269.             default:    *line++ = *prediction++;
  1270.                         break;
  1271.             }
  1272.         }
  1273.         *(line)=0;
  1274.     } else strcpy(line,prediction);
  1275. }
  1276.  
  1277. #pragma segment Main
  1278. GetOffscreen()
  1279. {
  1280.     GrafPtr  oldPort;
  1281.  
  1282.     SetPort(gText);
  1283.     GetFontInfo(&gNormFInfo);
  1284.     GetPort(&oldPort);
  1285.     OpenPort(&goffScreen);
  1286.     SetPort(oldPort);
  1287.     SetRect(&goffScreen.portRect,0,0,
  1288.             qd.screenBits.bounds.right-qd.screenBits.bounds.left,
  1289.             gNormFInfo.ascent+gNormFInfo.descent+gNormFInfo.leading);
  1290.     /* rowBytes is size of row, rounded up to an even number of bytes */
  1291.     goffScreen.portBits.rowBytes = (((goffScreen.portBits.bounds.right -
  1292.         goffScreen.portBits.bounds.left) + 15) >> 4) << 1;
  1293.         
  1294.     /* number of bytes in BitMap is rowBytes * number of rows */
  1295.     /* this calculation must be done with longs */
  1296.     goffScreen.portBits.baseAddr = NewPtr(goffScreen.portBits.rowBytes *
  1297.         (long) (goffScreen.portBits.bounds.bottom -
  1298.         goffScreen.portBits.bounds.top));
  1299.     SetPort(&goffScreen);
  1300.     TextFont(gSpecialFont);
  1301.     SetPort(gText);
  1302. }
  1303.  
  1304. #pragma segment Main
  1305. void DoNew()
  1306. {
  1307.     Boolean        good;
  1308.     Boolean        noBuffs=false;
  1309.     Ptr            storage;
  1310.     Ptr            predstorage;
  1311.     Rect        destRect, viewRect;
  1312.     DocumentPeek doc;
  1313.  
  1314.     predstorage=NewPtr(sizeof(OffscreenRecord));
  1315.     if (predstorage==nil) AlertUser(eNoWindow);
  1316.     gPredict=nil;
  1317.     if(gMac.hasColorQD){
  1318.         gPredict=GetNewCWindow(rPredictWindow,predstorage,(void *) -1);
  1319.     }else {
  1320.         gPredict=GetNewWindow(rPredictWindow,predstorage,(void *) -1);
  1321.     }
  1322.     if (gPredict==nil) AlertUser(eNoWindow);
  1323.     ((OffscreenPeek)gPredict)->fBackHandle        = nil;
  1324.     ((OffscreenPeek)gPredict)->fSelectHandle    = nil;
  1325.     
  1326.     NewOffscreenForWindow(gPredict,&noBuffs,&((OffscreenPeek)gPredict)->fBackHandle);
  1327.     NewOffscreenForWindow(gPredict,&noBuffs,&((OffscreenPeek)gPredict)->fSelectHandle);
  1328.  
  1329.     SetPort(gPredict);
  1330.     GetFNum(kFontName,&gSpecialFont);
  1331.     TextFont(gSpecialFont);
  1332.     TextSize(12);
  1333.     TextFace(0);
  1334.     GetFontInfo(&gFInfo);
  1335.     gPredScroll=GetNewControl(rPredScroll,gPredict);
  1336.  
  1337.     storage = NewPtr(sizeof(DocumentRecord));
  1338.     if ( storage != nil ) {
  1339.         gText = GetNewWindow(rTermWindow, storage, (WindowPtr) -1);
  1340.         if ( gText != nil ) {
  1341.             gNumDocuments += 1;            /* this will be decremented when we call DoCloseWindow */
  1342.             good = false;
  1343.             SetPort(gText);
  1344.             doc =  (DocumentPeek) gText;
  1345.             GetTERect(gText, &viewRect);
  1346.             destRect = viewRect;
  1347.             destRect.right = destRect.left + kMaxDocWidth;
  1348.             doc->docTE = TENew(&destRect, &viewRect);
  1349.             AdjustViewRect(doc->docTE);
  1350.             TEAutoView(true, doc->docTE);
  1351.             doc->docClik = (ProcPtr) (*doc->docTE)->clikLoop;
  1352.             (*doc->docTE)->clikLoop = (ClikLoopProcPtr) AsmClikLoop;
  1353.             
  1354.             good = doc->docTE != nil;    /* if TENew succeeded, we have a good document */
  1355.             if ( good ) {                /* good document? ╤ get scrollbars */
  1356.                 doc->docVScroll = GetNewControl(rVScroll, gText);
  1357.                 good = (doc->docVScroll != nil);
  1358.             }
  1359.             if ( good) {
  1360.                 doc->docHScroll = GetNewControl(rHScroll, gText);
  1361.                 good = (doc->docHScroll != nil);
  1362.             }
  1363.             
  1364.             if ( good ) {                /* good? ╤ adjust & draw the controls, draw the window */
  1365.                 /* false to AdjustScrollValues means musn╒t redraw; technically, of course,
  1366.                 the window is hidden so it wouldn╒t matter whether we called ShowControl or not. */
  1367.                 AdjustScrollValues(gText, false);
  1368.                 ShowWindow(gText);
  1369.                 GetOffscreen();
  1370.             } else {
  1371.                 DoCloseWindow(gText);    /* otherwise regret we ever created it... */
  1372.                 gText=nil;
  1373.                 AlertUser(eNoWindow);            /* and tell user */
  1374.             }
  1375.         } else
  1376.             DisposPtr(storage);            /* get rid of the storage if it is never used */
  1377.     }
  1378.     gChanged = false;
  1379. } /*DoNew*/
  1380.                 
  1381. #pragma segment Main
  1382. void DoKeyDown(EventRecord    *event)
  1383. {
  1384.     WindowPtr    window;
  1385.     char        key;
  1386.     TEHandle    te;
  1387.  
  1388.     window = FrontWindow();
  1389.     if ( window == gPredict)
  1390.         SelectWindow(gText);
  1391.     if ( IsAppWindow(window) ) {
  1392.         gChanged = true;
  1393.         te = ((DocumentPeek) gText)->docTE;
  1394.         key = event->message & charCodeMask;
  1395.         /* we have a char. for our window; see if we are still below TextEdit╒s
  1396.             limit for the number of characters (but deletes are always rad) */
  1397.         if ( key == kDelChar ||
  1398.                 (*te)->teLength - ((*te)->selEnd - (*te)->selStart) + 1 <
  1399.                 kMaxTELength ) {
  1400.  
  1401.             TEKey(key, te);
  1402.             NewContext();
  1403. #ifdef EVERYKEY
  1404.             update_the_model();  
  1405. #else
  1406.             if(key==13)
  1407.                 update_the_model();  
  1408. #endif                
  1409.             DrawNewPredictions();
  1410.  
  1411.             AdjustScrollbars(gText, false);
  1412.             AdjustTE(gText);
  1413.         } else
  1414.             AlertUser(eExceedChar);
  1415.     }
  1416. } /*DoKeyDown*/
  1417.  
  1418.  
  1419. #pragma segment Main
  1420. pascal void VActionProc(control,part)
  1421.     ControlHandle control;
  1422.     short        part;
  1423. {
  1424.     short        amount;
  1425.     WindowPtr    window;
  1426.     TEPtr        te;
  1427.     
  1428.     if ( part != 0 ) {                /* if it was actually in the control */
  1429.         window = (*control)->contrlOwner;
  1430.         te = *((DocumentPeek) window)->docTE;
  1431.         switch ( part ) {
  1432.             case inUpButton:
  1433.             case inDownButton:        /* one line */
  1434.                 amount = 1;
  1435.                 break;
  1436.             case inPageUp:            /* one page */
  1437.             case inPageDown:
  1438.                 amount = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight;
  1439.                 break;
  1440.         }
  1441.         if ( (part == inDownButton) || (part == inPageDown) )
  1442.             amount = -amount;        /* reverse direction for a downer */
  1443.         CommonAction(control, &amount);
  1444.         if ( amount != 0 )
  1445.             TEScroll(0, amount * te->lineHeight, ((DocumentPeek) window)->docTE);
  1446.     }
  1447. } /* VActionProc */
  1448.  
  1449.  
  1450. #pragma segment Main
  1451. pascal void HActionProc(control,part)
  1452.     ControlHandle control;
  1453.     short        part;
  1454. {
  1455.     short        amount;
  1456.     WindowPtr    window;
  1457.     TEPtr        te;
  1458.     
  1459.     if ( part != 0 ) {
  1460.         window = (*control)->contrlOwner;
  1461.         te = *((DocumentPeek) window)->docTE;
  1462.         switch ( part ) {
  1463.             case inUpButton:
  1464.             case inDownButton:        /* a few pixels */
  1465.                 amount = kButtonScroll;
  1466.                 break;
  1467.             case inPageUp:            /* a page */
  1468.             case inPageDown:
  1469.                 amount = te->viewRect.right - te->viewRect.left;
  1470.                 break;
  1471.         }
  1472.         if ( (part == inDownButton) || (part == inPageDown) )
  1473.             amount = -amount;        /* reverse direction */
  1474.         CommonAction(control, &amount);
  1475.         if ( amount != 0 )
  1476.             TEScroll(amount, 0, ((DocumentPeek) window)->docTE);
  1477.     }
  1478. } /* VActionProc */
  1479.  
  1480. #pragma segment Main
  1481. void DrawWindow(window)
  1482.     WindowPtr    window;
  1483. {
  1484.     SetPort(window);
  1485.     EraseRect(&window->portRect);
  1486.     DrawControls(window);
  1487.     DrawGrowIcon(window);
  1488.     TEUpdate(&window->portRect, ((DocumentPeek) window)->docTE);
  1489. } /*DrawWindow*/
  1490.  
  1491. #pragma segment Main
  1492. void GetLocalUpdateRgn(window,localRgn)
  1493.     WindowPtr    window;
  1494.     RgnHandle    localRgn;
  1495. {
  1496.     CopyRgn(((WindowPeek) window)->updateRgn, localRgn);    /* save old update region */
  1497.     OffsetRgn(localRgn, window->portBits.bounds.left, window->portBits.bounds.top);
  1498. } /* GetLocalUpdateRgn */
  1499.  
  1500.  
  1501. #pragma segment Main
  1502. void AdjustTE(window)
  1503.     WindowPtr    window;
  1504. {
  1505.     TEPtr        te;
  1506.     
  1507.     te = *((DocumentPeek)window)->docTE;
  1508.     TEScroll((te->viewRect.left - te->destRect.left) -
  1509.             GetCtlValue(((DocumentPeek)window)->docHScroll),
  1510.             (te->viewRect.top - te->destRect.top) -
  1511.                 (GetCtlValue(((DocumentPeek)window)->docVScroll) *
  1512.                 te->lineHeight),
  1513.             ((DocumentPeek)window)->docTE);
  1514. } /*AdjustTE*/
  1515.  
  1516. #pragma segment Main
  1517. void AdjustHV(isVert,control,docTE,canRedraw)
  1518.     Boolean        isVert;
  1519.     ControlHandle control;
  1520.     TEHandle    docTE;
  1521.     Boolean        canRedraw;
  1522. {
  1523.     short        value, lines, max;
  1524.     short        oldValue, oldMax;
  1525.     TEPtr        te;
  1526.     
  1527.     oldValue = GetCtlValue(control);
  1528.     oldMax = GetCtlMax(control);
  1529.     te = *docTE;                            /* point to TERec for convenience */
  1530.     if ( isVert ) {
  1531.         lines = te->nLines;
  1532.         /* since nLines isn╒t right if the last character is a return, check for that case */
  1533.         if ( *(*te->hText + te->teLength - 1) == kCrChar )
  1534.             lines += 1;
  1535.         max = lines - ((te->viewRect.bottom - te->viewRect.top) /
  1536.                 te->lineHeight);
  1537.     } else
  1538.         max = kMaxDocWidth - (te->viewRect.right - te->viewRect.left);
  1539.     
  1540.     if ( max < 0 ) max = 0;
  1541.     SetCtlMax(control, max);
  1542.     
  1543.     /* Must deref. after SetCtlMax since, technically, it could draw and therefore move
  1544.         memory. This is why we don╒t just do it once at the beginning. */
  1545.     te = *docTE;
  1546.     if ( isVert )
  1547.         value = (te->viewRect.top - te->destRect.top) / te->lineHeight;
  1548.     else
  1549.         value = te->viewRect.left - te->destRect.left;
  1550.     
  1551.     if ( value < 0 ) value = 0;
  1552.     else if ( value >  max ) value = max;
  1553.     
  1554.     SetCtlValue(control, value);
  1555.     /* now redraw the control if it needs to be and can be */
  1556.     if ( canRedraw || (max != oldMax) || (value != oldValue) )
  1557.         ShowControl(control);
  1558. } /*AdjustHV*/
  1559.  
  1560.  
  1561. /* Simply call the common adjust routine for the vertical and horizontal scrollbars. */
  1562.  
  1563. #pragma segment Main
  1564. void AdjustScrollValues(window,canRedraw)
  1565.     WindowPtr    window;
  1566.     Boolean        canRedraw;
  1567. {
  1568.     DocumentPeek doc;
  1569.     
  1570.     doc = (DocumentPeek)window;
  1571.     AdjustHV(true, doc->docVScroll, doc->docTE, canRedraw);
  1572.     AdjustHV(false, doc->docHScroll, doc->docTE, canRedraw);
  1573. } /*AdjustScrollValues*/
  1574.  
  1575.  
  1576. /*    Re-calculate the position and size of the viewRect and the scrollbars.
  1577.     kScrollTweek compensates for off-by-one requirements of the scrollbars
  1578.     to have borders coincide with the growbox. */
  1579.  
  1580. #pragma segment Main
  1581. void AdjustScrollSizes(window)
  1582.     WindowPtr    window;
  1583. {
  1584.     Rect        teRect;
  1585.     DocumentPeek doc;
  1586.     
  1587.     doc = (DocumentPeek) window;
  1588.     GetTERect(window, &teRect);                            /* start with TERect */
  1589.     (*doc->docTE)->viewRect = teRect;
  1590.     AdjustViewRect(doc->docTE);                            /* snap to nearest line */
  1591.     MoveControl(doc->docVScroll, window->portRect.right - kScrollbarAdjust, -1);
  1592.     SizeControl(doc->docVScroll, kScrollbarWidth, (window->portRect.bottom - 
  1593.                 window->portRect.top) - (kScrollbarAdjust - kScrollTweek));
  1594.     MoveControl(doc->docHScroll, -1, window->portRect.bottom - kScrollbarAdjust);
  1595.     SizeControl(doc->docHScroll, (window->portRect.right - 
  1596.                 window->portRect.left) - (kScrollbarAdjust - kScrollTweek),
  1597.                 kScrollbarWidth);
  1598. } /*AdjustScrollSizes*/
  1599.  
  1600.  
  1601. /* Turn off the controls by jamming a zero into their contrlVis fields (HideControl erases them
  1602.     and we don't want that). If the controls are to be resized as well, call the procedure to do that,
  1603.     then call the procedure to adjust the maximum and current values. Finally re-enable the controls
  1604.     by jamming a $FF in their contrlVis fields. */
  1605.  
  1606. #pragma segment Main
  1607. void AdjustScrollbars(window,needsResize)
  1608.     WindowPtr    window;
  1609.     Boolean        needsResize;
  1610. {
  1611.     DocumentPeek doc;
  1612.     
  1613.     doc = (DocumentPeek) window;
  1614.     /* First, turn visibility of scrollbars off so we won╒t get unwanted redrawing */
  1615.     (*doc->docVScroll)->contrlVis = kControlInvisible;    /* turn them off */
  1616.     (*doc->docHScroll)->contrlVis = kControlInvisible;
  1617.     if ( needsResize )                                    /* move & size as needed */
  1618.         AdjustScrollSizes(window);
  1619.     AdjustScrollValues(window, needsResize);            /* fool with max and current value */
  1620.     /* Now, restore visibility in case we never had to ShowControl during adjustment */
  1621.     (*doc->docVScroll)->contrlVis = kControlVisible;    /* turn them on */
  1622.     (*doc->docHScroll)->contrlVis = kControlVisible;
  1623. } /* AdjustScrollbars */
  1624.  
  1625. #pragma segment Main
  1626. void CommonAction(control,amount)
  1627.     ControlHandle control;
  1628.     short        *amount;
  1629. {
  1630.     short        value, max;
  1631.     
  1632.     value = GetCtlValue(control);    /* get current value */
  1633.     max = GetCtlMax(control);        /* and maximum value */
  1634.     *amount = value - *amount;
  1635.     if ( *amount < 0 )
  1636.         *amount = 0;
  1637.     else if ( *amount > max )
  1638.         *amount = max;
  1639.     SetCtlValue(control, *amount);
  1640.     *amount = value - *amount;        /* calculate the real change */
  1641. } /* CommonAction */
  1642.  
  1643. #pragma segment Main
  1644. void AdjustViewRect(docTE)
  1645.     TEHandle    docTE;
  1646. {
  1647.     TEPtr        te;
  1648.     
  1649.     te = *docTE;
  1650.     te->viewRect.bottom = (((te->viewRect.bottom - te->viewRect.top) / te->lineHeight)
  1651.                             * te->lineHeight) + te->viewRect.top;
  1652. } /*AdjustViewRect*/
  1653.  
  1654. #pragma segment Main
  1655. void GetTERect(window,teRect)
  1656.     WindowPtr    window;
  1657.     Rect        *teRect;
  1658. {
  1659.     *teRect = window->portRect;
  1660.     InsetRect(teRect, kTextMargin, kTextMargin);    /* adjust for margin */
  1661.     teRect->bottom = teRect->bottom - 15;        /* and for the scrollbars */
  1662.     teRect->right = teRect->right - 15;
  1663. } /*GetTERect*/
  1664.  
  1665. #pragma segment Main
  1666. pascal void PascalClikLoop()
  1667. {
  1668.     WindowPtr    window;
  1669.     RgnHandle    region;
  1670.     
  1671.     window = FrontWindow();
  1672.     region = NewRgn();
  1673.     GetClip(region);                    /* save clip */
  1674.     ClipRect(&window->portRect);
  1675.     AdjustScrollValues(window, true);    /* pass true for canRedraw */
  1676.     SetClip(region);                    /* restore clip */
  1677.     DisposeRgn(region);
  1678. } /* PascalClikLoop */
  1679.  
  1680.  
  1681. #pragma segment Main
  1682. pascal ProcPtr GetOldClikLoop()
  1683. {
  1684.     return ((DocumentPeek)FrontWindow())->docClik;
  1685. } /* GetOldClikLoop */
  1686.  
  1687.  
  1688. #pragma segment Main
  1689. void DoGrowWindow(window,event)
  1690.     WindowPtr    window;
  1691.     EventRecord    *event;
  1692. {
  1693.     long        growResult;
  1694.     Rect        tempRect;
  1695.     RgnHandle    tempRgn;
  1696.     DocumentPeek doc;
  1697.     
  1698.     SetPort(window);
  1699.     tempRect = qd.screenBits.bounds;                    /* set up limiting values */
  1700.     tempRect.left = kMinDocDim;
  1701.     tempRect.top = kMinDocDim;
  1702.     growResult = GrowWindow(window, event->where, &tempRect);
  1703.     /* see if it really changed size */
  1704.     if ( growResult != 0 ) {
  1705.         doc = (DocumentPeek) window;
  1706.         tempRect = (*doc->docTE)->viewRect;                /* save old text box */
  1707.         tempRgn = NewRgn();
  1708.         GetLocalUpdateRgn(window, tempRgn);                /* get localized update region */
  1709.         SizeWindow(window, LoWord(growResult), HiWord(growResult), true);
  1710.         ResizeWindow(window);
  1711.         /* calculate & validate the region that hasn╒t changed so it won╒t get redrawn */
  1712.         SectRect(&tempRect, &(*doc->docTE)->viewRect, &tempRect);
  1713.         ValidRect(&tempRect);                            /* take it out of update */
  1714.         InvalRgn(tempRgn);                                /* put back any prior update */
  1715.         DisposeRgn(tempRgn);
  1716.     }
  1717. } /* DoGrowWindow */
  1718.  
  1719.  
  1720. /*     Called when a mouseClick occurs in the zoom box of an active window.
  1721.     Everything has to get re-drawn here, so we don't mind that
  1722.     ResizeWindow invalidates the whole portRect. */
  1723.  
  1724. #pragma segment Main
  1725. void DoZoomWindow(window,part)
  1726.     WindowPtr    window;
  1727.     short        part;
  1728. {
  1729.     EraseRect(&window->portRect);
  1730.     ZoomWindow(window, part, window == FrontWindow());
  1731.     ResizeWindow(window);
  1732. } /*  DoZoomWindow */
  1733.  
  1734. #pragma segment Main
  1735. void ResizeWindow(window)
  1736.     WindowPtr    window;
  1737. {
  1738.     SetPort(window);
  1739.     AdjustScrollbars(window, true);
  1740.     AdjustTE(window);
  1741.     InvalRect(&window->portRect);
  1742. } /* ResizeWindow */
  1743.  
  1744.  
  1745.  
  1746. #pragma segment Main
  1747. pascal void PredActionProc(control,part)
  1748.     ControlHandle control;
  1749.     short        part;
  1750. {
  1751.     short        amount;
  1752.     short        value, max;
  1753.  
  1754.     
  1755.     if ( part != 0 ) {                /* if it was actually in the control */
  1756.         switch ( part ) {
  1757.             case inUpButton:
  1758.             case inDownButton:        /* one line */
  1759.                 amount = 1;
  1760.                 break;
  1761.             case inPageUp:            /* one page */
  1762.             case inPageDown:
  1763.                 amount = (gPredict->portRect.bottom-gPredict->portRect.top-20)/
  1764.                     (gFInfo.ascent+gFInfo.descent+gFInfo.leading);
  1765.                 break;
  1766.         }
  1767.         if ( (part == inDownButton) || (part == inPageDown) )
  1768.             amount = -amount;        /* reverse direction for a downer */
  1769.     
  1770.     value = GetCtlValue(control);    /* get current value */
  1771.     max = GetCtlMax(control);        /* and maximum value */
  1772.     amount = value - amount;
  1773.     if ( amount < 0 )
  1774.         amount = 0;
  1775.     else if ( amount > max )
  1776.         amount = max;
  1777.     SetCtlValue(control, amount);
  1778.     gPredScrollNum=GetCtlValue(control);
  1779.     DrawNewPredictions();
  1780.     }
  1781. } /* PredActionProc */
  1782.  
  1783. #pragma segment Main
  1784. void NewContext()
  1785. {
  1786.     TEHandle    te;
  1787.     CharsHandle    TEText;
  1788.     int            x;
  1789.  
  1790.     SetCtlValue(gPredScroll,0);
  1791.     gPredScrollNum=0;
  1792.     
  1793.     te = ((DocumentPeek) gText)->docTE;
  1794.     TECalText(te);
  1795.     TEText=TEGetText(te);
  1796.     
  1797.     for(x=(*te)->selStart;(x>0)&&(x>(*te)->selStart-128);x--);
  1798.     strncpy(ed_context,(char *) (*TEText)+x,(*te)->selStart-x);
  1799.     ed_context[(*te)->selStart-x]=0;
  1800. #ifdef DEBUG
  1801.     {
  1802.         KeyMap theKeys;
  1803.         GetKeys(&theKeys);
  1804.         if(theKeys[1] == 32773){
  1805.             debugstr(ed_context);
  1806.         }
  1807.     }
  1808. #endif
  1809. }
  1810.  
  1811.  
  1812. #pragma segment Prefs
  1813. pascal void DrawRndRect(theDialog,theItem)
  1814. DialogPtr    theDialog; 
  1815. short int    theItem;
  1816.  
  1817. {
  1818.     short int    iType;        /*returned item type*/
  1819.     Rect        iBox;               /*returned bounds rect*/
  1820.     Handle    iHdl;            /*returned item handle*/
  1821.     
  1822.     GetDItem(theDialog,theItem,&iType,&iHdl,&iBox); /*get the box*/
  1823.     InsetRect(&iBox,-4,-4);
  1824.     PenSize(3,3);
  1825.     FrameRoundRect(&iBox,10,10); 
  1826.     PenNormal();
  1827. } /*DrawRndRect*/
  1828.  
  1829. #pragma segment Prefs
  1830. pascal void DrawPopup(theDialog,theItem)
  1831. DialogPtr    theDialog; 
  1832. short int    theItem;
  1833.  
  1834. {
  1835.     short int    iType;        /*returned item type*/
  1836.     Rect        iBox;        /*returned bounds rect*/
  1837.     Handle        iHdl;        /*returned item handle*/
  1838.     Str255        CurText;
  1839.     int            wid,newWid,newLen;
  1840.     MenuHandle    theMenu;
  1841.     short        lastChoice;
  1842.     
  1843.     switch(theItem){
  1844.     case iFreqPop:
  1845.         theMenu = gFreqPop;
  1846.         lastChoice = gLastFreq;
  1847.         break;
  1848.     case iOrderPop:
  1849.         theMenu=gOrderPop;
  1850.         lastChoice = gLastOrder;
  1851.         break;
  1852.     default:
  1853.         abortit("Bad case in switch (DrawPopup)");
  1854.     }
  1855.     
  1856.     GetDItem(theDialog,theItem,&iType,&iHdl,&iBox); /*get the box*/
  1857.  
  1858.     GetItem(theMenu,lastChoice,CurText);
  1859.     wid    = (iBox.right-iBox.left)-(kLeftSlop+kRightSlop);
  1860.     newWid = StringWidth(CurText);
  1861.     if(newWid > wid) {
  1862.         newLen = CurText[0];
  1863.         wid -= CharWidth('╔');
  1864.         while((newWid > wid) && CurText[0]){
  1865.             newWid -= CharWidth(CurText[newLen]);
  1866.             newLen--;
  1867.         }
  1868.         CurText[++newLen]= '╔';
  1869.         CurText[0]=newLen;
  1870.     }
  1871.     FrameRect(&iBox);
  1872.     MoveTo(iBox.right, iBox.top+2);
  1873.     LineTo(iBox.right, iBox.bottom);
  1874.     LineTo(iBox.left,  iBox.bottom);
  1875.     MoveTo(iBox.left+kLeftSlop,iBox.bottom-kBotSlop);
  1876.     DrawString(CurText);
  1877. } /* DrawPopup */
  1878.         
  1879.  
  1880. #pragma segment Prefs
  1881. pascal Boolean PrefsFilter(theDialog,theEvent,itemHit)
  1882. DialogPtr    theDialog; 
  1883. EventRecord    *theEvent;
  1884. short int    *itemHit;
  1885. {
  1886.  
  1887.     char        key;           /*for enter/return*/
  1888.     Point        mouseLoc,popLoc;
  1889.     short        newChoice;
  1890.     long        chosen;
  1891.  
  1892.  
  1893.     SetPort(theDialog);
  1894.     switch (theEvent->what)        /*which event?*/
  1895.     {
  1896.     case keyDown:
  1897.     case autoKey:        /*she hit a key*/
  1898.         key = theEvent->message; /*get ascii code*/
  1899.         if ((key ==3) || (key == 13))
  1900.         {             /*she hit CR or Enter*/
  1901.             *itemHit = 1;    /*she hit the 1st item*/
  1902.             return(true);    /*we handled it*/
  1903.         } else if (!isdigit(key)&&(isprint(key))) {
  1904.             theEvent->what = nullEvent;
  1905.         }
  1906.         break;        /* case keydown, case autoKey */
  1907.     case mouseDown:    
  1908.         mouseLoc=theEvent->where;
  1909.         GlobalToLocal(&mouseLoc);
  1910.         switch(FindDItem(theDialog,mouseLoc) + 1){
  1911.         case iFreqPop:
  1912.             InvertRect(&gFreqPromptRect);
  1913.             InsertMenu(gFreqPop,-1);
  1914.             popLoc = TopLeft(gFreqRect);
  1915.             LocalToGlobal(&popLoc);
  1916.             CalcMenuSize(gFreqPop);
  1917.             chosen = PopUpMenuSelect(gFreqPop,popLoc.v,popLoc.h, gLastFreq);
  1918.             InvertRect(&gFreqPromptRect);
  1919.             DeleteMenu(mFreqPop);
  1920.             if(chosen){
  1921.                 newChoice = LoWord(chosen);
  1922.                 if(newChoice != gLastFreq){
  1923.                     SetItemMark(gFreqPop,gLastFreq,' ');
  1924.                     SetItemMark(gFreqPop,newChoice,checkMark);
  1925.                     gLastFreq = newChoice;
  1926.                     EraseRect(&gFreqRect);
  1927.                     DrawPopup(theDialog,iFreqPop);
  1928.                     *itemHit = iFreqPop;
  1929.                     return(true);
  1930.                 }
  1931.             }
  1932.             break;
  1933.         case iOrderPop:
  1934.             InvertRect(&gOrderPromptRect);
  1935.             InsertMenu(gOrderPop,-1);
  1936.             popLoc = TopLeft(gOrderRect);
  1937.             LocalToGlobal(&popLoc);
  1938.             CalcMenuSize(gOrderPop);
  1939.             chosen = PopUpMenuSelect(gOrderPop,popLoc.v,popLoc.h, gLastOrder);
  1940.             InvertRect(&gOrderPromptRect);
  1941.             DeleteMenu(mOrderPop);
  1942.             if(chosen){
  1943.                 newChoice = LoWord(chosen);
  1944.                 if(newChoice != gLastOrder){
  1945.                     SetItemMark(gOrderPop,gLastOrder,' ');
  1946.                     SetItemMark(gOrderPop,newChoice,checkMark);
  1947.                     gLastOrder = newChoice;
  1948.                     EraseRect(&gOrderRect);
  1949.                     DrawPopup(theDialog,iOrderPop);
  1950.                     *itemHit = iOrderPop;
  1951.                     return(true);
  1952.                 }
  1953.             }
  1954.             break;
  1955.         }
  1956.         break;                    
  1957.     }                     /*event switch*/
  1958.     return(false);  /* we╒re still here, so return false (we didn't handle the event) */
  1959. } /*PrefsFilter*/
  1960.  
  1961.  
  1962. #pragma segment Prefs
  1963. void DoPrefs()
  1964. {
  1965.     DialogPtr    PrefsDialog;
  1966.     short        item=0;
  1967.     Boolean        changed=false;
  1968.     Boolean        done=false;
  1969.     Handle        itemHand;
  1970.     short        itemType;
  1971.     Rect        itemRect;
  1972.     short        CtlVal;
  1973.     PrefHandle  newPrefs=NewHandle(sizeof(Preferences));
  1974.     Str255        Text;
  1975.     int            Value;
  1976.     int         err;
  1977.     char        errortxt[100];
  1978.     
  1979.     (**newPrefs)=(**gPrefs);
  1980.     MoveHHi((Handle)newPrefs);
  1981.     HLock((Handle)newPrefs);
  1982.     
  1983.     
  1984.     PrefsDialog = GetNewDialog(rPrefs,nil,(void *)-1);
  1985.     gFreqPop        = GetMenu(mFreqPop);
  1986.     gOrderPop    = GetMenu(mOrderPop);
  1987.     gLastFreq    = Log2((*newPrefs)->pMaxCount);
  1988.  
  1989.     gLastOrder    = (*newPrefs)->pOrder - 1;
  1990.  
  1991.     SetItemMark(gFreqPop,  gLastFreq,  checkMark);
  1992.     SetItemMark(gOrderPop, gLastOrder, checkMark);
  1993.  
  1994.     GetDItem(PrefsDialog,iUserItem,&itemType,&itemHand,&itemRect); 
  1995.     SetDItem(PrefsDialog,iUserItem,itemType,(Handle)DrawRndRect,&itemRect); /*install draw proc*/
  1996.  
  1997.     GetDItem(PrefsDialog,iFreqPop,&itemType,&itemHand,&gFreqRect);
  1998.     SetDItem(PrefsDialog,iFreqPop,itemType,(Handle)DrawPopup,&gFreqRect); /*install draw proc*/
  1999.  
  2000.     GetDItem(PrefsDialog,iOrderPop,&itemType,&itemHand,&gOrderRect);
  2001.     SetDItem(PrefsDialog,iOrderPop,itemType,(Handle)DrawPopup,&gOrderRect); /*install draw proc*/
  2002.  
  2003.     GetDItem(PrefsDialog,iFreqPrompt,&itemType,&itemHand,&gFreqPromptRect);
  2004.  
  2005.     GetDItem(PrefsDialog,iOrderPrompt,&itemType,&itemHand,&gOrderPromptRect);
  2006.          
  2007.     GetDItem(PrefsDialog,iStartUpEdit,&itemType,&itemHand,&itemRect); 
  2008.     SelIText(PrefsDialog,iStartUpEdit,0,32767);
  2009.     
  2010.     ShowWindow(PrefsDialog);   /*make it visible*/
  2011.     
  2012.     SetPort(PrefsDialog);
  2013.     while(!done){
  2014.         GetDItem(PrefsDialog,iStopAtCRBox,&itemType,&itemHand,&itemRect);
  2015.         SetCtlValue((ControlHandle)itemHand,(*newPrefs)->pstopAtCR);
  2016.         GetDItem(PrefsDialog,iShowSpcTabBox,&itemType,&itemHand,&itemRect);
  2017.         SetCtlValue((ControlHandle)itemHand,(*newPrefs)->pshowSpecial);
  2018.         GetDItem(PrefsDialog,iStartUpEdit,&itemType,&itemHand,&itemRect); 
  2019.         NumToString((*newPrefs)->pStartup,Text);
  2020.         SetIText(itemHand,Text);
  2021.         SelIText(PrefsDialog,iStartUpEdit,0,32767);
  2022.         item=0;
  2023.         while((item!=iOk) && (item != iCancel)){
  2024.             ModalDialog(PrefsFilter,&item);
  2025.             GetDItem(PrefsDialog,item,&itemType,&itemHand,&itemRect);
  2026.             switch(item){
  2027.                 case iStopAtCRBox:
  2028.                     CtlVal=GetCtlValue((ControlHandle)itemHand);
  2029.                     SetCtlValue((ControlHandle)itemHand,!CtlVal);
  2030.                     (*newPrefs)->pstopAtCR = !CtlVal;
  2031.                     break;
  2032.                 case iShowSpcTabBox:
  2033.                     CtlVal=GetCtlValue((ControlHandle)itemHand);
  2034.                     SetCtlValue((ControlHandle)itemHand,!CtlVal);
  2035.                     (*newPrefs)->pshowSpecial = !CtlVal;
  2036.                     break;
  2037.                 
  2038.                 case iPrimeButton:
  2039.                     if(GetPrimeFile(true,newPrefs) || ((*newPrefs)->pHasPrime != (*gPrefs)->pHasPrime))
  2040.                         changed=true;
  2041.                     break;
  2042.                 case iZeroButton:
  2043.                     if(GetPrimeFile(false,newPrefs) || ((*newPrefs)->pHasZero != (*gPrefs)->pHasZero))
  2044.                         changed=true;
  2045.                     break;
  2046.                 case iFreqPop:
  2047.                 case iOrderPop:
  2048.                     break;
  2049.                 case iStartUpEdit:    
  2050.                     changed=true;
  2051.                     break;
  2052.             }
  2053.         }
  2054.         
  2055.         if(item==iOk){
  2056.             done=true;
  2057.             GetDItem(PrefsDialog,iStartUpEdit,&itemType,&itemHand,&itemRect); 
  2058.             GetIText(itemHand, Text);
  2059.             StringToNum(Text,&Value);
  2060.             if(Value>=0) {
  2061.                 (*newPrefs)->pStartup=Value;
  2062.             }else {
  2063.                 (*newPrefs)->pStartup=0;
  2064.                 ParamText(Text,"\p0","\p░",nil);
  2065.                 if(done) Alert(rOutOfRange,nil);
  2066.                 done=false;
  2067.             }
  2068.             if((*newPrefs)->pMaxCount !=1<<gLastFreq)  changed = true;
  2069.             (*newPrefs)->pMaxCount = 1<<gLastFreq;
  2070.             if((*newPrefs)->pOrder      != gLastOrder+1) changed = true;            
  2071.             (*newPrefs)->pOrder       = gLastOrder+1;
  2072.         
  2073.             if(done && changed)
  2074.                 Alert(rPrefChanges,nil);
  2075.             if(done){
  2076.                 (**gPrefs)=(**newPrefs);
  2077.             }
  2078.         }
  2079.         if(item==iCancel){
  2080.             done=true;
  2081.         }
  2082.     }
  2083.     HUnlock((Handle)newPrefs);
  2084.     DisposHandle((Handle)newPrefs);
  2085.     DisposDialog(PrefsDialog);
  2086.     DisposeMenu(gFreqPop);
  2087.     DisposeMenu(gOrderPop);
  2088.     ChangedResource((Handle)gPrefs);
  2089.     if((err=ResError())!=noErr){
  2090.         sprintf(errortxt,"Resource Manager Error(ChangeRes): %d",err);
  2091.         abortit(errortxt);
  2092.     }
  2093.     WriteResource((Handle)gPrefs);
  2094.     if((err=ResError())!=noErr){
  2095.         sprintf(errortxt,"Resource Manager Error(WriteRes): %d",err);
  2096.         abortit(errortxt);
  2097.     }
  2098.     if(IsAppWindow(FrontWindow())){
  2099.         DrawNewPredictions();
  2100.     }
  2101. }
  2102.  
  2103. #pragma segment Prefs
  2104. void GetPrefs()
  2105. {
  2106.     short OldVol;
  2107.     int PrefFile;
  2108.     int err;
  2109.     char errortxt[100];
  2110.     Str255 PrefName,OldName;
  2111.     GetIndString(&PrefName, rNameStrings, iPrefsName);
  2112.     GetVol(&OldName,&OldVol);
  2113.     if(SetVol(nil,gMac.sysVRefNum))
  2114.         DebugStr("\p SetVol to System Folder failed.");
  2115.     if((PrefFile=OpenResFile(PrefName))==-1){
  2116.         CreateResFile(PrefName);
  2117.         if((PrefFile=OpenResFile(PrefName)) == -1){
  2118.             gPrefs = (PrefHandle) NewHandle(sizeof(Preferences));
  2119.             SetUpDefaults();
  2120.             return;
  2121.         }
  2122.         UseResFile(PrefFile);
  2123.         gPrefs = (PrefHandle) NewHandle(sizeof(Preferences));
  2124.         SetUpDefaults();
  2125.         AddResource((Handle)gPrefs,rPrefType,rPrefID,PrefName);
  2126.         if((err=ResError())!=noErr){
  2127.             sprintf(errortxt,"Resource Manager Error(AddRes1): %d",err);
  2128.             abortit(errortxt);
  2129.         }
  2130.         UpdateResFile(PrefFile);
  2131.     }else{
  2132.         UseResFile(PrefFile);
  2133.         if((gPrefs = (PrefHandle) GetResource(rPrefType,rPrefID))==0){
  2134.             gPrefs = (PrefHandle) NewHandle(sizeof(Preferences));
  2135.             SetUpDefaults();
  2136.             AddResource((Handle)gPrefs,rPrefType,rPrefID,PrefName);
  2137.             if((err=ResError())!=noErr){
  2138.                 sprintf(errortxt,"Resource Manager Error(AddRes2): %d",err);
  2139.                 abortit(errortxt);
  2140.             }
  2141.             UpdateResFile(PrefFile);
  2142.         }
  2143.     }
  2144.     SetVol(nil,OldVol);
  2145.     gStartPrefs = (PrefHandle) NewHandle(sizeof(Preferences));
  2146.     (**gStartPrefs)=(**gPrefs);
  2147.     MoveHHi((Handle)gStartPrefs);
  2148.     HLock((Handle)gStartPrefs);
  2149.  
  2150. }
  2151.  
  2152. #pragma segment Prefs
  2153.  
  2154. SetUpDefaults()
  2155. {
  2156.     (*gPrefs)->pshowSpecial=true;
  2157.     (*gPrefs)->pstopAtCR=true;
  2158.     (*gPrefs)->pMaxCount=128;
  2159.     (*gPrefs)->pOrder=8;
  2160.     (*gPrefs)->pHasPrime=false;
  2161.     (*gPrefs)->pStartup=32000;
  2162.     (*gPrefs)->pHasZero=false;
  2163.     (*gPrefs)->pShowPredInBuffer=true;
  2164. }
  2165.  
  2166.  
  2167. pascal void DrawHelp(theDialog,theItem)
  2168. DialogPtr    theDialog; 
  2169. short int    theItem;
  2170.  
  2171. {
  2172.     short int    iType; 
  2173.     Rect        iBox;   
  2174.     Handle    iHdl; 
  2175.  
  2176.     GetDItem(theDialog,theItem,&iType,&iHdl,&iBox); 
  2177.     MoveTo((iBox.right-iBox.left)/2-(StringWidth("\pPut Help Here")/2),
  2178.             (iBox.bottom-iBox.top)/2);
  2179.     DrawString("\pPut Help Here");
  2180.     
  2181.  
  2182.     FrameRect(&iBox);            
  2183. } /*DrawHelp*/
  2184.  
  2185. pascal Boolean HelpFilter(theDialog,theEvent,itemHit)
  2186. DialogPtr    theDialog; 
  2187. EventRecord    *theEvent;
  2188. short int    *itemHit;
  2189.  
  2190. {
  2191.     char        key;           /*for enter/return*/
  2192.     short int    iType;          /*returned item type*/
  2193.     Rect        iBox;             /*returned boundsrect*/
  2194.     Handle    iHdl;           /*returned item handle*/
  2195.     Point        mouseLoc;        /*we'll play w/ mouse*/
  2196.  
  2197.     SetPort(theDialog);
  2198.     switch (theEvent->what)        /*which event?*/
  2199.     {
  2200.         case keyDown:
  2201.         case autoKey:        /*he hit a key*/
  2202.             key = theEvent->message; /*get ascii code*/
  2203.             if ((key ==3) || (key == 13))
  2204.             {             /*he hit CR or Enter*/
  2205.                 *itemHit = 1;    /*he hit the 1st item*/
  2206.                 return(true);    /*we handled it*/
  2207.             } /*he hit CR or enter*/
  2208.                  break;        /* case keydown, case autoKey */
  2209.         case mouseDown:        /*he clicked*/
  2210.                 mouseLoc = theEvent->where;    /*get the mouse pos'n*/
  2211.                 GlobalToLocal(&mouseLoc);    /*convert to local*/
  2212.                 GetDItem(theDialog,2,&iType,&iHdl,&iBox); /*get our box*/
  2213.                 if (PtInRect(mouseLoc,&iBox))  
  2214.             {             /*he hit our item*/
  2215.                     InvertRect(&iBox);
  2216.                        *itemHit = 2;    /*he hit the userItem*/
  2217.                        return(true);    /*we handled it*/
  2218.                 } /*if he hit our userItem*/
  2219.                  break; /*case mouseDown */
  2220.     }                     /*event switch*/
  2221.     return(false);  /* we╒re still here, so return false (we didn't
  2222.                        handle the event) */
  2223. } /*HelpFilter*/
  2224.  
  2225.  
  2226.